package com.alumni_circle.core.config;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alumni_circle.core.entity.rbac.LoginUser;
import com.alumni_circle.core.utils.GetOpen;
import com.alumni_circle.entity.me.User;
import com.alumni_circle.service.me.impl.UserServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * @author 龙小虬
 * @since 2020-08-29 00:32
 */
@Component
public class WeChatAuthenticationProvider implements AuthenticationProvider {

    @Resource
    UserServiceImpl userService;

    @Resource
    RedisCache redisCache;

    private final List<GrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("CAN_SEARCH"));

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String openid = GetOpen.sendGet(authentication.getName());
        if(!openid.contains("err")){
            //核实身份成功,将用户信息存入  SecurityContextHolder
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("openid",openid);
            User user = userService.getOne(userQueryWrapper);

            if(ObjectUtil.hasEmpty(user)){
                // 新用户赋予公共权限
                User newUser = new User();
                newUser.setRole("ROLE_COMMON");
                newUser.setOpenid(openid);
                userService.save(newUser);
                String str = IdUtil.simpleUUID();
                newUser.setUsername(str);
                newUser.setUsername(str);
                UserDetails loginUser = createLoginUser(newUser,redisCache.getCacheSet(newUser.getRole()));
                UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(loginUser,null,authorities);
                SecurityContextHolder.getContext().setAuthentication(authRequest);
                return authRequest;
            }
            UserDetails loginUser = createLoginUser(user,redisCache.getCacheSet(user.getRole()));
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(loginUser,null,authorities);
            SecurityContextHolder.getContext().setAuthentication(authRequest);
            return authRequest;
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }

    public static UserDetails createLoginUser(User user, Set set){
        return new LoginUser(user,set);
    }
}
